package com.meiya.hugegraph.mock;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Random;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.common.serialization.StringSerializer;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;

/**
 * 模拟账户数据生成器
 * 生成与交易数据相关联的账户信息
 */
public class AccountDataGenerator {
    private static final String BOOTSTRAP_SERVERS = "192.168.182.128:9092";
    private static final String TOPIC = "account-data";
    private static final int NUM_ACCOUNTS = 10; // 生成少量账户数据
    private static final int DELAY_MS = 100;

    private static final Random random = new Random();
    private static final ObjectMapper objectMapper = new ObjectMapper();
    
    // 添加批次任务记录ID，确保同一批次的数据使用相同的task_record_id
    private static String batchTaskRecordId = UUID.randomUUID().toString();
    
    // 添加批次级别的clue_id
    private static Long batchClueId = Long.parseLong("101" + String.format("%06d", random.nextInt(999999)));

    // 存储银行卡号与用户信息(姓名和身份证号)的映射，确保同一账号的用户信息一致
    private static final Map<String, UserInfo> userInfoMap = new HashMap<>();
    
    // 银行类型与代码映射
    private static final Map<String, String> BANK_CODE_MAP = new HashMap<String, String>() {{
        put("中国建设银行", "105");
        put("中国工商银行", "102");
        put("中国农业银行", "103");
        put("中国银行", "104");
    }};

    // 存储生成的账户信息，供TransactionDataGenerator使用
    private static final Map<String, AccountInfo> accountInfoMap = new HashMap<>();

    public static void main(String[] args) {
        // 为每批次生成新的任务记录ID和clue_id
        batchTaskRecordId = UUID.randomUUID().toString();
        batchClueId = Long.parseLong("101" + String.format("%06d", random.nextInt(999999)));
        System.out.println("生成新批次任务记录ID: " + batchTaskRecordId + ", clue_id: " + batchClueId);
        
        Properties props = new Properties();
        props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, BOOTSTRAP_SERVERS);
        props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
        props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());

        try (KafkaProducer<String, String> producer = new KafkaProducer<>(props)) {
            System.out.println("开始生成并发送账户数据...");

            for (int i = 0; i < NUM_ACCOUNTS; i++) {
                AccountInfo accountInfo = generateAccountInfo();
                String record = generateAccountRecord(accountInfo);
                producer.send(new ProducerRecord<>(TOPIC, record));

                // 存储账户信息
                accountInfoMap.put(accountInfo.bankCard, accountInfo);

                if (DELAY_MS > 0) {
                    TimeUnit.MILLISECONDS.sleep(DELAY_MS);
                }
            }

            System.out.println("数据生成完成，共发送 " + NUM_ACCOUNTS + " 条记录");
            // 打印生成的账户信息，方便调试
            accountInfoMap.forEach((card, info) ->
                    System.out.println("Generated Account: " + card + ", Bank: " + info.bankName));

            // 生成交易数据
            TransactionDataGenerator.main(args);
        } catch (Exception e) {
            System.err.println("发送数据时出错: " + e.getMessage());
            e.printStackTrace();
        }
    }

    private static String generateAccountRecord(AccountInfo accountInfo) {
        try {
            ObjectNode record = objectMapper.createObjectNode();

            // 按照需求中的account字段规范填充数据
            record.put("clue_id", accountInfo.clueId);
            record.put("jykh", accountInfo.bankCard);
            record.put("jyzh", accountInfo.bankCard);
            record.put("zhkhmc", accountInfo.accountName); // 账户开户名称
            record.put("khrzjhm", accountInfo.idNumber); // 客户人证件号码
            record.put("zhkhsj", "2020-01-01 10:00:00"); // 账户开户时间
            record.put("zhye", String.valueOf(10000 + random.nextInt(90000))); // 账户余额
            record.put("kyye", String.valueOf(8000 + random.nextInt(80000))); // 可用余额
            record.put("bz", "CNY"); // 币种
            record.put("khwddm", "SZ" + (1000 + random.nextInt(9000))); // 开户网点代码
            record.put("khwd", "深圳市分行" + random.nextInt(10) + "支行"); // 开户网点
            record.put("zhzt", "正常"); // 账户状态
            record.put("chbzmc", "人民币"); // 钞/汇标志名称
            record.put("khrzjlx", "身份证"); // 客户人证件类型
            record.put("xhrq", ""); // 销户日期
            record.put("zhlx", "储蓄账户"); // 账户类型
            record.put("khlxfs", "13" + String.format("%09d", random.nextInt(1000000000))); // 客户联系方式
            record.put("txdz", "广东省深圳市南山区科技园"); // 通信地址
            record.put("lxdh", "0755-" + (10000000 + random.nextInt(90000000))); // 联系电话
            record.put("dlr", ""); // 代理人
            record.put("dlrdh", ""); // 代理人电话
            record.put("bzbz", ""); // 标志标志
            record.put("khsf", "个人"); // 客户身份
            record.put("khcs", "深圳"); // 客户城市
            record.put("zhkhyh", accountInfo.bankName); // 账户开户银行
            record.put("khdm", "KH" + (10000 + random.nextInt(90000))); // 客户代码
            record.put("frdb", ""); // 法人代表
            record.put("khgszzhm", ""); // 客户工商执照号码
            record.put("frdbzjhm", ""); // 法人代表证件号码
            record.put("zzdz", "广东省深圳市南山区科技园"); // 住宅地址
            record.put("yzbm", "518000"); // 邮政编码
            record.put("dbrzjhm", ""); // 担保人证件号码
            record.put("yxdz", "test" + random.nextInt(100) + "@example.com"); // 邮箱地址
            record.put("glzjzh", ""); // 关联资金账号
            record.put("dsnsh", ""); // 地税纳税号
            record.put("dwdh", ""); // 单位电话
            record.put("dbrzjlx", ""); // 担保人证件类型
            record.put("zzdh", ""); // 住宅电话
            record.put("frdbzjlx", ""); // 法人代表证件类型
            record.put("gsnsh", ""); // 国税纳税号
            record.put("dwdz", ""); // 单位地址
            record.put("gzdw", ""); // 工作单位
            record.put("xhwd", ""); // 销户网点
            record.put("zhjysj", "2025-02-18 10:20:21"); // 最后交易时间
            record.put("zhxhyh", ""); // 账户销户银行
            record.put("rwlsh", "RW" + System.currentTimeMillis()); // 任务流水号
            record.put("a_yhlx", accountInfo.bankName); // 银行类型
            record.put("origin_data_id", "OD" + System.currentTimeMillis()); // 原始数据ID
            record.put("crrq", accountInfo.crrq); // 插入日期 - 使用当前时间
            record.put("ukey", random.nextLong()); // 唯一键
            record.put("task_record_id", batchTaskRecordId); // 使用批次任务记录ID

            return objectMapper.writeValueAsString(record);
        } catch (Exception e) {
            throw new RuntimeException("生成账户记录时出错", e);
        }
    }

    private static AccountInfo generateAccountInfo() {
        AccountInfo info = new AccountInfo();
        info.clueId = batchClueId; // 使用批次级别的clue_id
        info.bankCard = generateBankCard();
        info.bankName = BANK_CODE_MAP.keySet().toArray(new String[0])[random.nextInt(BANK_CODE_MAP.size())];
        
        // 检查该银行卡是否已有对应的用户信息
        UserInfo userInfo = userInfoMap.get(info.bankCard);
        if (userInfo == null) {
            // 如果没有，生成新的用户信息并存储
            userInfo = new UserInfo();
            userInfo.accountName = "张三" + random.nextInt(100);
            userInfo.idNumber = generateIdNumber();
            userInfoMap.put(info.bankCard, userInfo);
        }
        
        // 使用已存储的用户信息
        info.accountName = userInfo.accountName;
        info.idNumber = userInfo.idNumber;
        info.crrq = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        info.taskRecordId = batchTaskRecordId;
        return info;
    }

    private static String generateBankCard() {
        StringBuilder card = new StringBuilder("621700");
        for (int i = 0; i < 10; i++) {
            card.append(random.nextInt(10));
        }
        String bankCard = card.toString();
        
        // 如果生成的银行卡已存在，则重新生成
        if (accountInfoMap.containsKey(bankCard) || userInfoMap.containsKey(bankCard)) {
            return generateBankCard();
        }
        
        return bankCard;
    }
    
    private static String generateIdNumber() {
        // 生成18位身份证号
        StringBuilder id = new StringBuilder();
        id.append("652922"); // 区域码
        id.append(String.format("%04d", 1980 + random.nextInt(20))); // 年
        id.append(String.format("%02d", 1 + random.nextInt(12))); // 月
        id.append(String.format("%02d", 1 + random.nextInt(28))); // 日
        id.append(String.format("%04d", random.nextInt(9999))); // 顺序码
        return id.toString();
    }

    // 用户信息数据结构
    private static class UserInfo {
        public String accountName;
        public String idNumber;
    }

    // 账户信息数据结构
    public static class AccountInfo {
        public Long clueId;
        public String bankCard;
        public String bankName;
        public String accountName;
        public String idNumber;
        public String crrq;
        public String taskRecordId;
    }

    // 获取已生成的账户信息
    public static Map<String, AccountInfo> getAccountInfoMap() {
        return accountInfoMap;
    }

    // 获取当前批次的任务记录ID
    public static String getBatchTaskRecordId() {
        return batchTaskRecordId;
    }

    // 获取当前批次的clue_id
    public static Long getBatchClueId() {
        return batchClueId;
    }
} 